﻿using System;
using BuzzX8.Xmpp.StreamElements.Builders;
using BuzzX8.Xmpp.StreamElements.Stanza;
using NUnit.Framework;

namespace BuzzX8.Xmpp.Test.StreamElements.Builders
{
    public static class BuilderUtils
    {
        public static void VerifyPresenceTypeBuild(PresenceStanzaType type, string attributeValue)
        {
            VerifyTypeAttributeBuild<PresenceStanzaType, PresenceStanza, PresenceStanzaBuilder>("presence", type, attributeValue);
        }

        public static void VerifyMessageTypeBuild(MessageStanzaType type, string attributeValue)
        {
            VerifyTypeAttributeBuild<MessageStanzaType, MessageStanza, MessageStanzaBuilder>("message", type, attributeValue);
        }

        public static void VerifyTypeAttributeBuild<TType, TElement, TBuilder>(string stanzaName, TType expectedType, string attributeValue) 
            where TElement : Stanza<TType>
            where TBuilder : StanzaBuilder<TType, TElement>
        {
            TBuilder stanzaBuilder = GetInitializedBuilder<TBuilder>(stanzaName);
            stanzaBuilder.AddAttribute("type", attributeValue);

            TElement stanza = stanzaBuilder.Get();
            Assert.AreEqual(expectedType, stanza.Type);
        }

        public static PresenceStanza BuildPresenceWithNode(string nodeName, string nodeValue)
        {
            return BuildStanzaWithNode<PresenceStanzaType, PresenceStanza, PresenceStanzaBuilder>("presence", nodeName, nodeValue);
        }

        public static MessageStanza BuildMessageStanzaWithNode(string nodeName, string nodeValue)
        {
            return BuildStanzaWithNode<MessageStanzaType, MessageStanza, MessageStanzaBuilder>("message", nodeName, nodeValue);
        }

        public static TElement BuildStanzaWithNode<TType, TElement, TBuilder>(string stanzaName, string nodeName, string nodeValue)
            where TElement : Stanza<TType>
            where TBuilder : StanzaBuilder<TType, TElement>
        {
            TBuilder builder = GetInitializedBuilder<TBuilder>(stanzaName);
            builder.StartNewElement(stanzaName);
            builder.StartNode(nodeName);
            builder.SetNodeValue(nodeValue);
            builder.EndNode();
            return builder.Get();
        }

        private static TBuilder GetInitializedBuilder<TBuilder>(string elementName) where TBuilder : StreamElementBuilder
        {
            TBuilder builder = Activator.CreateInstance<TBuilder>();
            builder.StartNewElement(elementName);
            return builder;
        }
    }
}
